from django.shortcuts import render, redirect
from django.db.models import F
from datetime import datetime
from ShopOL.settings import alipay_private_path, alipay_key_path, notify_url, return_url
from goods.models import Goods
from .models import ShoppingCart, OrderInfo, OrderGoods
from rest_framework import viewsets, permissions, authentication, mixins
from .serializers import ShopCartSerializer, ShopCartDetailSerializer, OrderInfoSerializes, OrderDetailInfoSerializes
from user_operation.permission import IsOwnerOrReadOnly
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.views import APIView
from utils.alipay import AliPay
from rest_framework.response import Response


# Create your views here.


class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能
    list:
        购物车详情
    create:
        加入购物车
    delete:
        删除购物车记录
    """
    queryset = ShoppingCart.objects.all().order_by('-add_time')
    # serializer_class = ShopCartSerializer
    authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthentication)
    permission_classes = (IsOwnerOrReadOnly, permissions.IsAuthenticated)
    lookup_field = 'goods_id'

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)

    def perform_destroy(self, instance):
        instance.delete()

    def get_serializer_class(self):
        if self.action == 'list':
            return ShopCartDetailSerializer
        else:
            return ShopCartSerializer


class OrderInfoViewSet(viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.DestroyModelMixin,
                       mixins.ListModelMixin, mixins.RetrieveModelMixin):
    """
    订单管理
    list:
        获取个人订单列表
    delete:
        删除订单
    create:
        新增订单
    """
    queryset = OrderInfo.objects.all().order_by('-add_time')
    # serializer_class = OrderInfoSerializes
    authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthentication)
    permission_classes = (IsOwnerOrReadOnly, permissions.IsAuthenticated)

    def get_queryset(self):
        return OrderInfo.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        order = serializer.save()
        shop_cats = ShoppingCart.objects.filter(user=self.request.user)
        for shop_cat in shop_cats:
            OrderGoods(
                order=order,
                goods_num=shop_cat.nums,
                goods=shop_cat.goods,
            ).save()
            Goods.objects.filter(id=shop_cat.goods.id).update(storage_num=F('storage_num') - shop_cat.nums)

    def perform_destroy(self, instance):
        if instance.pay_status == 'WAIT_BUYER_PAY':
            operate_goods = OrderGoods.objects.filter(order_id=instance.id)
            for goods in operate_goods:
                Goods.objects.filter(id=goods.goods_id).update(storage_num=F('storage_num') + goods.goods_num)
        instance.delete()

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return OrderDetailInfoSerializes
        return OrderInfoSerializes


class AlipayView(APIView):
    def get(self, request):
        """
        处理支付宝return_url
        :param request:
        :return:
        """
        processed_dict = {}
        for key, value in request.GET.items():
            processed_dict[key] = value
        sign = processed_dict.pop('sign', None)
        alipay = AliPay(
            appid="2016093000630230",
            app_notify_url=notify_url,
            app_private_key_path=alipay_private_path,
            alipay_public_key_path=alipay_key_path,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            debug=True,  # 默认False,
            return_url=return_url,
        )
        verify_re = alipay.verify(processed_dict, sign)
        if verify_re is True:
            order_sn = processed_dict.get('out_trade_no', None)
            trade_no = processed_dict.get('trade_no', None)
            existed_order = OrderInfo.objects.filter(order_sn=order_sn)
            existed_order.update(trade_no=trade_no,
                                 pay_status='TRADE_SUCCESS',
                                 pay_time=datetime.now())
            for order in existed_order:
                exist_goods = OrderGoods.objects.filter(order_id=order.id)
                for goods in exist_goods:
                    Goods.objects.filter(id=goods.goods_id).update(sold_num=F('sold_num') + goods.goods_num)
            # response = redirect('http://47.101.217.26/')
            # response.set_cookie("next_path", "pay", max_age=2)
            return redirect('http://47.101.217.26/#/app/home/member/order')
        else:
            return redirect('http://47.101.217.26/')

    def post(self, request):
        """
        处理支付宝notify_url
        :param request:
        :return:
        """
        processed_dict = {}
        for key, value in request.POST.items():
            processed_dict[key] = value
        sign = processed_dict.pop("sign", None)
        alipay = AliPay(
            appid="2016093000630230",
            app_notify_url=notify_url,
            app_private_key_path=alipay_private_path,
            alipay_public_key_path=alipay_key_path,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            debug=True,  # 默认False,
            return_url=return_url
        )
        verify_re = alipay.verify(processed_dict, sign)
        if verify_re is True:
            order_sn = processed_dict.get('out_trade_no', None)
            trade_no = processed_dict.get('trade_no', None)
            trade_status = processed_dict.get('trade_status', None)
            existed_order = OrderInfo.objects.filter(order_sn=order_sn)
            existed_order.update(trade_no=trade_no,
                                 pay_status=trade_status,
                                 pay_time=datetime.now())
            if trade_status == 'TRADE_SUCCESS':
                for order in existed_order:
                    exist_goods = OrderGoods.objects.filter(order_id=order.id)
                    for goods in exist_goods:
                        Goods.objects.filter(id=goods.goods_id).update(sold_num=F('sold_num') + goods.goods_num)
            return Response('success')
